package com.chdwmp.product.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConstants;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.chdwmp.product.bean.CommonResponse;
import com.chdwmp.product.bean.pay.AliPrePayReqVo;
import com.chdwmp.product.bean.pay.OrderInfoBo;
import com.chdwmp.product.bean.pay.OrderQueryVo;
import com.chdwmp.product.constant.ApplicationProperties;
import com.chdwmp.product.constant.PayConstants;
import com.chdwmp.product.constant.Status;
import com.chdwmp.product.exception.CommonException;
import com.chdwmp.product.pay.ali.AlipayConfig;
import com.chdwmp.product.pay.ali.AlipayUtil;
import com.chdwmp.product.pay.wx.ResponseUtil;
import com.chdwmp.product.service.PayService;
import com.chdwmp.product.utils.DateUtils;
import com.dtflys.forest.annotation.Get;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/pay")
@CrossOrigin("*")
@Api(description = "支付模块", tags = {"支付模块接口控制层"})
public class PayController {

    @Autowired
    PayService payService;
    @Autowired
    AlipayConfig alipayConfig;

    @Autowired
    ApplicationProperties applicationProperties;

    private static Logger logger = LoggerFactory.getLogger(PayController.class);



    @PostMapping(value = "/alipay/create/orderCode")
    @ApiOperation(value = "生成支付宝订单", httpMethod = "POST", response = CommonResponse.class)
    public CommonResponse createOrderCode(@RequestBody AliPrePayReqVo aliPrePayReqVo) throws Exception {
        return new CommonResponse(payService.createOrderCode(aliPrePayReqVo));
    }




    @GetMapping(value = "/alipay/prepay/{order_code}")
    @ApiOperation(value = "支付宝APP支付-统一下单", httpMethod = "GET", response = CommonResponse.class)
    public CommonResponse alipayPrePay(@PathVariable String order_code) throws Exception {
        logger.info("(支付宝支付 统一下单) 订单编号：" + order_code + " 开始下单=================================>");

        if(StrUtil.isEmpty(order_code))
            throw new CommonException(Status.MISS_REQUIRED_PARAMETER);
        OrderInfoBo orderInfo = payService.getOrderInfo(order_code);
        if (null == orderInfo)
            throw new CommonException(Status.ORDER_NOT_EXISTS.getMsg());
        Integer order_cost = orderInfo.getOrder_cost();
        if(order_cost <= 0)
            throw new CommonException(Status.ORDER_PRICE_LESS_THAN_ZERO.getMsg());

        //公共参数
        Map<String, String> params = new HashMap<>();
        params.put("app_id", alipayConfig.getAppID());//支付宝分配给开发者的应用ID
        params.put("method", alipayConfig.getAlipayPrePayUrl());//接口名称
        params.put("format", "JSON");//仅支持JSON
        params.put("charset", alipayConfig.getCharset());//请求使用的编码格式，如utf-8,gbk,gb2312等
        params.put("sign_type", alipayConfig.getSignType());//商户生成签名字符串所使用的签名算法类型，目前支持RSA2和RSA，推荐使用RSA2
        params.put("timestamp", DateUtils.currentDateTime());//发送请求的时间，格式"yyyy-MM-dd HH:mm:ss"
        params.put("version", "1.0");//	调用的接口版本，固定为：1.0
        params.put("notify_url", alipayConfig.getNotifyUrl());//支付宝服务器主动通知商户服务器里指定的页面http/https路径。建议商户使用https

        Map<String, String> biz_content = new HashMap();
        biz_content.put("body", "产品包");//对一笔交易的具体描述信息。如果是多种商品，请将商品描述字符串累加传给body。
        biz_content.put("subject", "产品包-序列号");//商品的标题/交易标题/订单标题/订单关键字等。
        biz_content.put("out_trade_no", order_code);//商户网站唯一订单号
        biz_content.put("timeout_express", "30m");//设置未付款支付宝交易的超时时间，一旦超时，该笔交易就会自动被关闭。当用户进入支付宝收银台页面（不包括登录页面），会触发即刻创建支付宝交易，此时开始计时。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        if (applicationProperties.is_pro){
            biz_content.put("total_amount", String.valueOf(order_cost));//订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]
//            biz_content.put("total_amount", "0.01");
        }else {
            biz_content.put("total_amount", "0.01");//订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]
        }
        biz_content.put("seller_id", alipayConfig.getPartner());//收款支付宝用户ID。 如果该值为空，则默认为商户签约账号对应的支付宝用户ID
        biz_content.put("product_code", "QUICK_MSECURITY_PAY");//销售产品码，商家和支付宝签约的产品码，为固定值QUICK_MSECURITY_PAY
        params.put("biz_content", JSONObject.toJSONString(biz_content));

        String signContent = AlipayUtil.getSignContent(params,Boolean.FALSE);
        logger.info("(支付宝支付 统一下单) 订单编号：" + order_code + "下单 签名前参数：" + signContent);
        String sign = AlipaySignature.rsa256Sign(signContent,alipayConfig.getPrivateKey(), "utf-8");
        logger.info("(支付宝支付 统一下单) 订单编号：" + order_code + "下单 签名：" + sign);

        StringBuffer result = new StringBuffer ();
        String signContentEncoder = AlipayUtil.getSignContent(params,Boolean.TRUE);
        result.append(signContentEncoder).append("&sign=").append(URLEncoder.encode(sign, "utf-8"));
        logger.info("(支付宝支付 统一下单) 订单编号：" + order_code + "下单 返回结果：" + result.toString());

        payService.updateOrderPrePayStatus(order_code, PayConstants.OrderPayWay.ZFB,orderInfo.getOrder_cost(),null);

        return  new CommonResponse(result.toString());
    }


    @PostMapping(value = "/alipay/notify")
    @ApiOperation(value = "支付宝APP支付-支付通知", httpMethod = "POST", response = CommonResponse.class)
    public void alipayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {

        logger.info("(支付宝支付 支付结果通知) 开始回调=================================>");
        Map<String, String> params = AlipayUtil.getRequestParams(request);

        logger.info("(支付宝支付 支付结果通知) 回调结果：" + JSON.toJSONString(params));
        String seller_id = params.get("seller_id"); // 买家付款账号
        String app_id = params.get("app_id"); // 支付宝分配给开发者的应用Id
        BigDecimal total_amount = new BigDecimal(params.get("total_amount"));//支付金额
        String out_trade_no = params.get("out_trade_no");// 商户订单号
        String trade_no = params.get("trade_no");// 支付宝交易号
        String trade_status = params.get("trade_status");// 交易状态

        //执行验签
        String result = "fail";
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), AlipayConstants.CHARSET_UTF8,alipayConfig.getSignType());
        if (signVerified) {
            logger.info("(支付宝支付 支付结果通知) alipayNotify验签成功 订单编号:" + out_trade_no + " 支付宝交易号:" + trade_no + " 交易状态:" + trade_status);
            if (trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")) {
                OrderInfoBo orderInfo = payService.getOrderInfo(out_trade_no);
                boolean flag = true;
//                if (applicationProperties.is_pro){
//                    flag = null != orderInfo && orderInfo.getOrder_cost() == total_amount.intValue() && alipayConfig.getPartner().equals(seller_id) && alipayConfig.getAppID().equals(app_id);
//                }else {
//                    flag =(null != orderInfo) && (BigDecimal.valueOf(0.01D).doubleValue() == total_amount.doubleValue()) && (this.alipayConfig.getPartner().equals(seller_id)) && (this.alipayConfig.getAppID().equals(app_id));
//                }
//                if (flag) {
                    // 支付成功后执行相关业务
                    logger.info("(支付宝支付 支付结果通知) alipayNotify支付成功 订单编号:"+out_trade_no+" 支付金额:"+total_amount);
                    //处理自己业务逻辑 把供应商购买的产品
                    logger.info("开始添加关系表----");
                    payService.addAgentUserReation(out_trade_no);
                    logger.info("结束添加关系表----");

                    logger.info("开始更新订单的状态----");
                    payService.updateOrderHasPayStatus(out_trade_no, PayConstants.OrderPayWay.ZFB,Integer.valueOf(orderInfo.getOrder_cost()),trade_no);
                    logger.info("结束更新订单状态-----");
                    result = "success";
//                }
            }
        } else {
            logger.info("(支付宝支付 支付结果通知) alipayNotify验签失败 订单编号:" + out_trade_no + " 支付宝交易号:" + trade_no + " 交易状态:" + trade_status);
        }
        logger.info("(支付宝支付 支付结果通知) 回调结束 响应支付宝服务端信息：" + result);
        ResponseUtil.renderText(response,result);
    }


    @Transactional
    @PostMapping(value = "/alipay/trade/query")
    @ApiOperation(value = "支付宝APP支付-交易查询", httpMethod = "POST", response = CommonResponse.class)
    public CommonResponse alipayNotify(@RequestBody OrderQueryVo orderQueryVo) throws Exception {
        if(StrUtil.isEmpty(orderQueryVo.getOrderCode()))
            throw new CommonException(Status.MISS_REQUIRED_PARAMETER);
        logger.info("(支付宝支付 交易查询) 订单编号：" + orderQueryVo.getOrderCode() + " 开始=================================>");

        String serverUrl = alipayConfig.getTradQueryUrl();
        String appId = alipayConfig.getAppID();
        String privateKey = alipayConfig.getPrivateKey();
        String format = "json";
        String charset = alipayConfig.getCharset();
        String alipayPulicKey = alipayConfig.getAlipayPublicKey();
        String signType = alipayConfig.getSignType();

        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPulicKey, signType);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();//创建API对应的request类

        JSONObject params = new JSONObject ();
        params.put("out_trade_no",orderQueryVo.getOrderCode());
        request.setBizContent(params.toJSONString());//设置业务参数
        AlipayTradeQueryResponse response = alipayClient.execute(request);//通过alipayClient调用API，获得对应的response类

        //根据response中的结果继续业务逻辑处理
        JSONObject result = new JSONObject ();
        if(response.isSuccess()){
            //交易状态：WAIT_BUYER_PAY（交易创建，等待买家付款）、
            // TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）、
            // TRADE_SUCCESS（交易支付成功）、
            // TRADE_FINISHED（交易结束，不可退款）
//            result = response.getTradeStatus();
            if (response.getTradeStatus().equals("TRADE_FINISHED") || response.getTradeStatus().equals("TRADE_SUCCESS")) {
                logger.info("(支付宝支付 交易查询) 订单编号：" + orderQueryVo.getOrderCode() + " 支付成功 结果：" + response.getBody());
                result.put("payCode",Status.PAY_SUCCESS.getCode());
                result.put("payMsg",Status.PAY_SUCCESS.getMsg());
                //处理自己业务逻辑 把供应商购买的产品
               // payService.addAgentUserReation(orderQueryVo.getOrderCode());

                //TODO 先挪到这边 等到回调好了 再走正常的逻辑

                //ice.updateOrderHasPayStatus(orderQueryVo.getOrderCode(), PayConstants.OrderPayWay.ZFB,Integer.valueOf(orderInfo.getOrder_cost()),orderQueryVo.getTradeNo());
            }else {
                result.put("payCode",Status.PAY_FAIL.getCode());
                result.put("payMsg",Status.PAY_FAIL.getMsg());
                logger.info("(支付宝支付 交易查询) 订单编号：" + orderQueryVo.getOrderCode() + " 支付不成功 结果：" + response.getBody());
            }
        } else {
            result.put("payCode",Status.PAY_FAIL.getCode());
            result.put("payMsg",Status.PAY_FAIL.getMsg());
            logger.info("(支付宝支付 交易查询) 订单编号：" + orderQueryVo.getOrderCode() + " 调用失败 错误码：" + response.getSubCode() + "msg:" + response.getSubMsg());
        }

        logger.info("(支付宝支付 交易查询) 订单编号：" + orderQueryVo.getOrderCode() + " 结果：" + result.toString());
        return new CommonResponse(result);
    }

//    @Transactional
//    @GetMapping(value = "/alipay/trade/query/{order_code}")
//    @ApiOperation(value = "支付宝APP支付-交易查询", httpMethod = "GET", response = CommonResponse.class)
//    public CommonResponse alipayNotify(@PathVariable String order_code) throws Exception {
//        if(StrUtil.isEmpty(order_code))
//            throw new CommonException(Status.MISS_REQUIRED_PARAMETER);
//        logger.info("(支付宝支付 交易查询) 订单编号：" + order_code + " 开始=================================>");
//
//        String serverUrl = alipayConfig.getTradQueryUrl();
//        String appId = alipayConfig.getAppID();
//        String privateKey = alipayConfig.getPrivateKey();
//        String format = "json";
//        String charset = alipayConfig.getCharset();
//        String alipayPulicKey = alipayConfig.getAlipayPublicKey();
//        String signType = alipayConfig.getSignType();
//
//        //获得初始化的AlipayClient
//        AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPulicKey, signType);
//        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();//创建API对应的request类
//
//        JSONObject params = new JSONObject ();
//        params.put("out_trade_no",order_code);
//        request.setBizContent(params.toJSONString());//设置业务参数
//        AlipayTradeQueryResponse response = alipayClient.execute(request);//通过alipayClient调用API，获得对应的response类
//
//        //根据response中的结果继续业务逻辑处理
//        JSONObject result = new JSONObject ();
//        if(response.isSuccess()){
//            //交易状态：WAIT_BUYER_PAY（交易创建，等待买家付款）、
//            // TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）、
//            // TRADE_SUCCESS（交易支付成功）、
//            // TRADE_FINISHED（交易结束，不可退款）
////            result = response.getTradeStatus();
//            if (response.getTradeStatus().equals("TRADE_FINISHED") || response.getTradeStatus().equals("TRADE_SUCCESS")) {
//                logger.info("(支付宝支付 交易查询) 订单编号：" + order_code + " 支付成功 结果：" + response.getBody());
//                result.put("payCode",Status.PAY_SUCCESS.getCode());
//                result.put("payMsg",Status.PAY_SUCCESS.getMsg());
//                //处理自己业务逻辑 把供应商购买的产品
//                payService.addAgentUserReation(order_code);
//            }else {
//                result.put("payCode",Status.PAY_FAIL.getCode());
//                result.put("payMsg",Status.PAY_FAIL.getMsg());
//                logger.info("(支付宝支付 交易查询) 订单编号：" + order_code + " 支付不成功 结果：" + response.getBody());
//            }
//        } else {
//            result.put("payCode",Status.PAY_FAIL.getCode());
//            result.put("payMsg",Status.PAY_FAIL.getMsg());
//            logger.info("(支付宝支付 交易查询) 订单编号：" + order_code + " 调用失败 错误码：" + response.getSubCode() + "msg:" + response.getSubMsg());
//        }
//
//        logger.info("(支付宝支付 交易查询) 订单编号：" + order_code + " 结果：" + result.toString());
//        return new CommonResponse(result);
//    }
}
